જાળવણી યોગ્ય, માપી શકાય તેવી અને પરીક્ષણ યોગ્ય એપ્લિકેશન્સ બનાવવા માટે જાવાસ્ક્રિપ્ટ મોડ્યુલ આર્કિટેક્ચર અને ડિઝાઇન પેટર્નનું અન્વેષણ કરો. વ્યવહારુ ઉદાહરણો અને શ્રેષ્ઠ પદ્ધતિઓ શોધો.
જાવાસ્ક્રિપ્ટ મોડ્યુલ આર્કિટેક્ચર: ડિઝાઇન પેટર્નનો અમલ
જાવાસ્ક્રિપ્ટ, આધુનિક વેબ ડેવલપમેન્ટનો પાયાનો પથ્થર, ગતિશીલ અને ઇન્ટરેક્ટિવ વપરાશકર્તા અનુભવો માટે પરવાનગી આપે છે. જોકે, જેમ જેમ જાવાસ્ક્રિપ્ટ એપ્લિકેશન્સ જટિલતામાં વધે છે, તેમ સારી રીતે સંરચિત કોડની જરૂરિયાત સર્વોપરી બને છે. અહીં જ મોડ્યુલ આર્કિટેક્ચર અને ડિઝાઇન પેટર્ન અમલમાં આવે છે, જે જાળવણીક્ષમ, માપી શકાય તેવી અને પરીક્ષણક્ષમ એપ્લિકેશન્સ બનાવવા માટે એક રોડમેપ પૂરો પાડે છે. આ માર્ગદર્શિકા વિવિધ મોડ્યુલ પેટર્નના મુખ્ય ખ્યાલો અને વ્યવહારુ અમલીકરણોમાં ઊંડાણપૂર્વક જાય છે, જે તમને સ્વચ્છ, વધુ મજબૂત જાવાસ્ક્રિપ્ટ કોડ લખવા માટે સશક્ત બનાવે છે.
મોડ્યુલ આર્કિટેક્ચર શા માટે મહત્વનું છે
ચોક્કસ પેટર્નમાં ડૂબકી મારતા પહેલા, મોડ્યુલ આર્કિટેક્ચર શા માટે જરૂરી છે તે સમજવું મહત્વપૂર્ણ છે. નીચેના ફાયદાઓ ધ્યાનમાં લો:
- સંગઠન: મોડ્યુલ્સ સંબંધિત કોડને એકસાથે સમાવે છે, જે તાર્કિક માળખાને પ્રોત્સાહન આપે છે અને મોટા કોડબેઝને નેવિગેટ કરવા અને સમજવામાં સરળ બનાવે છે.
- જાળવણીક્ષમતા: મોડ્યુલની અંદર કરવામાં આવેલા ફેરફારો સામાન્ય રીતે એપ્લિકેશનના અન્ય ભાગોને અસર કરતા નથી, જે અપડેટ્સ અને બગ ફિક્સને સરળ બનાવે છે.
- પુનઃઉપયોગક્ષમતા: મોડ્યુલ્સનો ઉપયોગ વિવિધ પ્રોજેક્ટ્સમાં ફરીથી કરી શકાય છે, જે વિકાસ સમય અને પ્રયત્નોને ઘટાડે છે.
- પરીક્ષણક્ષમતા: મોડ્યુલ્સ સ્વ-સમાયેલ અને સ્વતંત્ર રહેવા માટે રચાયેલ છે, જે યુનિટ ટેસ્ટ લખવાનું સરળ બનાવે છે.
- માપનીયતા: મોડ્યુલ્સ સાથે બનેલી સારી રીતે આર્કિટેક્ચરવાળી એપ્લિકેશન્સ પ્રોજેક્ટ વધતાની સાથે વધુ કાર્યક્ષમ રીતે માપી શકાય છે.
- સહયોગ: મોડ્યુલ્સ ટીમવર્કને સુવિધા આપે છે, કારણ કે બહુવિધ વિકાસકર્તાઓ એકબીજાના કામમાં દખલ કર્યા વિના એક સાથે વિવિધ મોડ્યુલ્સ પર કામ કરી શકે છે.
જાવાસ્ક્રિપ્ટ મોડ્યુલ સિસ્ટમ્સ: એક ઝાંખી
જાવાસ્ક્રિપ્ટમાં મોડ્યુલારિટીની જરૂરિયાતને પહોંચી વળવા માટે ઘણી મોડ્યુલ સિસ્ટમ્સ વિકસિત થઈ છે. ડિઝાઇન પેટર્નને અસરકારક રીતે લાગુ કરવા માટે આ સિસ્ટમ્સને સમજવી મહત્વપૂર્ણ છે.
CommonJS
CommonJS, જે Node.js વાતાવરણમાં પ્રચલિત છે, મોડ્યુલ્સ આયાત કરવા માટે require() અને નિકાસ કરવા માટે module.exports અથવા exports નો ઉપયોગ કરે છે. આ એક સિંક્રનસ મોડ્યુલ લોડિંગ સિસ્ટમ છે.
// myModule.js
module.exports = {
myFunction: function() {
console.log('Hello from myModule!');
}
};
// app.js
const myModule = require('./myModule');
myModule.myFunction();
ઉપયોગના કિસ્સાઓ: મુખ્યત્વે સર્વર-સાઇડ જાવાસ્ક્રિપ્ટ (Node.js) અને ક્યારેક ફ્રન્ટ-એન્ડ પ્રોજેક્ટ્સ માટે બિલ્ડ પ્રક્રિયાઓમાં વપરાય છે.
AMD (Asynchronous Module Definition)
AMD એસિંક્રનસ મોડ્યુલ લોડિંગ માટે રચાયેલ છે, જે તેને વેબ બ્રાઉઝર્સ માટે યોગ્ય બનાવે છે. તે મોડ્યુલ્સ જાહેર કરવા માટે define() અને તેમને આયાત કરવા માટે require() નો ઉપયોગ કરે છે. RequireJS જેવી લાઇબ્રેરીઓ AMD નો અમલ કરે છે.
// myModule.js (using RequireJS syntax)
define(function() {
return {
myFunction: function() {
console.log('Hello from myModule (AMD)!');
}
};
});
// app.js (using RequireJS syntax)
require(['./myModule'], function(myModule) {
myModule.myFunction();
});
ઉપયોગના કિસ્સાઓ: ઐતિહાસિક રીતે બ્રાઉઝર-આધારિત એપ્લિકેશન્સમાં વપરાય છે, ખાસ કરીને જેમને ડાયનેમિક લોડિંગ અથવા બહુવિધ નિર્ભરતાઓ સાથે કામ કરવાની જરૂર હોય છે.
ES Modules (ESM)
ES Modules, જે સત્તાવાર રીતે ECMAScript સ્ટાન્ડર્ડનો ભાગ છે, એક આધુનિક અને પ્રમાણિત અભિગમ પ્રદાન કરે છે. તે મોડ્યુલ્સ આયાત કરવા માટે import અને નિકાસ કરવા માટે export (export default) નો ઉપયોગ કરે છે. ES Modules હવે આધુનિક બ્રાઉઝર્સ અને Node.js દ્વારા વ્યાપકપણે સમર્થિત છે.
// myModule.js
export function myFunction() {
console.log('Hello from myModule (ESM)!');
}
// app.js
import { myFunction } from './myModule.js';
myFunction();
ઉપયોગના કિસ્સાઓ: આધુનિક જાવાસ્ક્રિપ્ટ ડેવલપમેન્ટ માટે પસંદગીની મોડ્યુલ સિસ્ટમ, જે બ્રાઉઝર અને સર્વર-સાઇડ બંને વાતાવરણને સપોર્ટ કરે છે, અને ટ્રી-શેકિંગ ઓપ્ટિમાઇઝેશનને સક્ષમ કરે છે.
જાવાસ્ક્રિપ્ટ મોડ્યુલ્સ માટે ડિઝાઇન પેટર્ન
ચોક્કસ લક્ષ્યો હાંસલ કરવા માટે જાવાસ્ક્રિપ્ટ મોડ્યુલ્સ પર ઘણી ડિઝાઇન પેટર્ન લાગુ કરી શકાય છે, જેમ કે સિંગલટન બનાવવું, ઇવેન્ટ્સ હેન્ડલ કરવું, અથવા વિવિધ રૂપરેખાંકનો સાથે ઓબ્જેક્ટ્સ બનાવવું. અમે વ્યવહારુ ઉદાહરણો સાથે કેટલીક સામાન્ય રીતે વપરાતી પેટર્નનું અન્વેષણ કરીશું.
૧. સિંગલટન પેટર્ન
સિંગલટન પેટર્ન ખાતરી કરે છે કે એપ્લિકેશનના જીવનચક્ર દરમ્યાન ક્લાસ અથવા ઓબ્જેક્ટનું માત્ર એક જ ઇન્સ્ટન્સ બનાવવામાં આવે છે. આ ડેટાબેઝ કનેક્શન અથવા વૈશ્વિક રૂપરેખાંકન ઓબ્જેક્ટ જેવા સંસાધનોનું સંચાલન કરવા માટે ઉપયોગી છે.
// Using an immediately invoked function expression (IIFE) to create the singleton
const singleton = (function() {
let instance;
function createInstance() {
const object = new Object({ name: 'Singleton Instance' });
return object;
}
return {
getInstance: function() {
if (!instance) {
instance = createInstance();
}
return instance;
},
};
})();
// Usage
const instance1 = singleton.getInstance();
const instance2 = singleton.getInstance();
console.log(instance1 === instance2); // Output: true
console.log(instance1.name); // Output: Singleton Instance
સમજૂતી:
- એક IIFE (Immediately Invoked Function Expression) એક ખાનગી સ્કોપ બનાવે છે, જે `instance` ના આકસ્મિક ફેરફારને અટકાવે છે.
- `getInstance()` પદ્ધતિ ખાતરી કરે છે કે માત્ર એક જ ઇન્સ્ટન્સ ક્યારેય બનાવવામાં આવે છે. પ્રથમ વખત તેને બોલાવવામાં આવે ત્યારે, તે ઇન્સ્ટન્સ બનાવે છે. પછીના કોલ્સ હાલના ઇન્સ્ટન્સને પરત કરે છે.
ઉપયોગના કિસ્સાઓ: વૈશ્વિક રૂપરેખાંકન સેટિંગ્સ, લોગિંગ સેવાઓ, ડેટાબેઝ કનેક્શન્સ, અને એપ્લિકેશન સ્ટેટનું સંચાલન.
૨. ફેક્ટરી પેટર્ન
ફેક્ટરી પેટર્ન ઓબ્જેક્ટ્સના કોંક્રિટ ક્લાસનો ઉલ્લેખ કર્યા વિના ઓબ્જેક્ટ્સ બનાવવા માટે એક ઇન્ટરફેસ પ્રદાન કરે છે. તે તમને ચોક્કસ માપદંડો અથવા રૂપરેખાંકનોના આધારે ઓબ્જેક્ટ્સ બનાવવાની મંજૂરી આપે છે, જે લવચીકતા અને કોડ પુનઃઉપયોગક્ષમતાને પ્રોત્સાહન આપે છે.
// Factory function
function createCar(type, options) {
switch (type) {
case 'sedan':
return new Sedan(options);
case 'suv':
return new SUV(options);
default:
return null;
}
}
// Car classes (implementation)
class Sedan {
constructor(options) {
this.type = 'Sedan';
this.color = options.color || 'white';
this.model = options.model || 'Unknown';
}
getDescription() {
return `This is a ${this.color} ${this.model} Sedan.`
}
}
class SUV {
constructor(options) {
this.type = 'SUV';
this.color = options.color || 'black';
this.model = options.model || 'Unknown';
}
getDescription() {
return `This is a ${this.color} ${this.model} SUV.`
}
}
// Usage
const mySedan = createCar('sedan', { color: 'blue', model: 'Camry' });
const mySUV = createCar('suv', { model: 'Explorer' });
console.log(mySedan.getDescription()); // Output: This is a blue Camry Sedan.
console.log(mySUV.getDescription()); // Output: This is a black Explorer SUV.
સમજૂતી:
- `createCar()` ફંક્શન ફેક્ટરી તરીકે કામ કરે છે.
- તે ઇનપુટ તરીકે `type` અને `options` લે છે.
- `type` ના આધારે, તે સંબંધિત કાર ક્લાસનું ઇન્સ્ટન્સ બનાવે છે અને પરત કરે છે.
ઉપયોગના કિસ્સાઓ: વિવિધ રૂપરેખાંકનો સાથે જટિલ ઓબ્જેક્ટ્સ બનાવવું, બનાવટ પ્રક્રિયાને અમૂર્ત કરવી, અને હાલના કોડમાં ફેરફાર કર્યા વિના નવા ઓબ્જેક્ટ પ્રકારોને સરળતાથી ઉમેરવાની મંજૂરી આપવી.
૩. ઓબ્ઝર્વર પેટર્ન
ઓબ્ઝર્વર પેટર્ન ઓબ્જેક્ટ્સ વચ્ચે એક-થી-ઘણા નિર્ભરતા વ્યાખ્યાયિત કરે છે. જ્યારે એક ઓબ્જેક્ટ (સબજેક્ટ) સ્થિતિ બદલે છે, ત્યારે તેના તમામ આશ્રિતો (ઓબ્ઝર્વર્સ) ને સૂચિત અને આપમેળે અપડેટ કરવામાં આવે છે. આ ડિકપલિંગ અને ઇવેન્ટ-ડ્રિવન પ્રોગ્રામિંગને સુવિધા આપે છે.
class Subject {
constructor() {
this.observers = [];
}
subscribe(observer) {
this.observers.push(observer);
}
unsubscribe(observer) {
this.observers = this.observers.filter(obs => obs !== observer);
}
notify(data) {
this.observers.forEach(observer => observer.update(data));
}
}
class Observer {
constructor(name) {
this.name = name;
}
update(data) {
console.log(`${this.name} received: ${data}`);
}
}
// Usage
const subject = new Subject();
const observer1 = new Observer('Observer 1');
const observer2 = new Observer('Observer 2');
subject.subscribe(observer1);
subject.subscribe(observer2);
subject.notify('Hello, observers!'); // Observer 1 received: Hello, observers! Observer 2 received: Hello, observers!
subject.unsubscribe(observer1);
subject.notify('Another update!'); // Observer 2 received: Another update!
સમજૂતી:
- `Subject` ક્લાસ ઓબ્ઝર્વર્સ (સબ્સ્ક્રાઇબર્સ) નું સંચાલન કરે છે.
- `subscribe()` અને `unsubscribe()` પદ્ધતિઓ ઓબ્ઝર્વર્સને નોંધણી અને અનરજિસ્ટર કરવાની મંજૂરી આપે છે.
- `notify()` દરેક નોંધાયેલા ઓબ્ઝર્વરની `update()` પદ્ધતિને બોલાવે છે.
- `Observer` ક્લાસ `update()` પદ્ધતિને વ્યાખ્યાયિત કરે છે જે ફેરફારો પર પ્રતિક્રિયા આપે છે.
ઉપયોગના કિસ્સાઓ: વપરાશકર્તા ઇન્ટરફેસમાં ઇવેન્ટ હેન્ડલિંગ, રીઅલ-ટાઇમ ડેટા અપડેટ્સ, અને એસિંક્રનસ ઓપરેશન્સનું સંચાલન. ઉદાહરણોમાં UI તત્વોને અપડેટ કરવું જ્યારે ડેટા બદલાય (દા.ત., નેટવર્ક વિનંતીથી), આંતર-ઘટક સંચાર માટે pub/sub સિસ્ટમનો અમલ કરવો, અથવા એક પ્રતિક્રિયાશીલ સિસ્ટમ બનાવવી જ્યાં એપ્લિકેશનના એક ભાગમાં ફેરફારો અન્યત્ર અપડેટ્સને ટ્રિગર કરે છે.
૪. મોડ્યુલ પેટર્ન
મોડ્યુલ પેટર્ન એ સ્વ-સમાયેલ, પુનઃઉપયોગી કોડ બ્લોક્સ બનાવવા માટે એક મૂળભૂત તકનીક છે. તે જાહેર અને ખાનગી સભ્યોને સમાવે છે, જે નામકરણ સંઘર્ષોને અટકાવે છે અને માહિતી છુપાવવાને પ્રોત્સાહન આપે છે. તે ઘણીવાર ખાનગી સ્કોપ બનાવવા માટે IIFE (Immediately Invoked Function Expression) નો ઉપયોગ કરે છે.
const myModule = (function() {
// Private variables and functions
let privateVariable = 'Hello';
function privateFunction() {
console.log('This is a private function.');
}
// Public interface
return {
publicMethod: function() {
console.log(privateVariable);
privateFunction();
},
publicVariable: 'World'
};
})();
// Usage
myModule.publicMethod(); // Output: Hello This is a private function.
console.log(myModule.publicVariable); // Output: World
// console.log(myModule.privateVariable); // Error: privateVariable is not defined (accessing private variables is not allowed)
સમજૂતી:
- એક IIFE એક ક્લોઝર બનાવે છે, જે મોડ્યુલની આંતરિક સ્થિતિને સમાવે છે.
- IIFE ની અંદર જાહેર કરાયેલા ચલો અને ફંક્શન્સ ખાનગી છે.
- `return` સ્ટેટમેન્ટ જાહેર ઇન્ટરફેસને ખુલ્લું પાડે છે, જેમાં મોડ્યુલની બહારથી સુલભ પદ્ધતિઓ અને ચલોનો સમાવેશ થાય છે.
ઉપયોગના કિસ્સાઓ: કોડનું આયોજન કરવું, પુનઃઉપયોગી ઘટકો બનાવવું, તર્કને સમાવવું, અને નામકરણ સંઘર્ષો અટકાવવા. આ ઘણા મોટા પેટર્નનો મુખ્ય બિલ્ડિંગ બ્લોક છે, જેનો ઉપયોગ ઘણીવાર સિંગલટન અથવા ફેક્ટરી પેટર્ન જેવી અન્ય પેટર્ન સાથે સંયોજનમાં થાય છે.
૫. રિવિલિંગ મોડ્યુલ પેટર્ન
મોડ્યુલ પેટર્નનું એક ભિન્ન સ્વરૂપ, રિવિલિંગ મોડ્યુલ પેટર્ન માત્ર ચોક્કસ સભ્યોને પરત કરેલા ઓબ્જેક્ટ દ્વારા ખુલ્લા પાડે છે, અમલીકરણની વિગતો છુપાવીને રાખે છે. આ મોડ્યુલના જાહેર ઇન્ટરફેસને સ્પષ્ટ અને સમજવામાં સરળ બનાવી શકે છે.
const revealingModule = (function() {
let privateVariable = 'Secret Message';
function privateFunction() {
console.log('Inside privateFunction');
}
function publicGet() {
return privateVariable;
}
function publicSet(value) {
privateVariable = value;
}
// Reveal public members
return {
get: publicGet,
set: publicSet,
// You can also reveal privateFunction (but usually it is hidden)
// show: privateFunction
};
})();
// Usage
console.log(revealingModule.get()); // Output: Secret Message
revealingModule.set('New Secret');
console.log(revealingModule.get()); // Output: New Secret
// revealingModule.privateFunction(); // Error: revealingModule.privateFunction is not a function
સમજૂતી:
- ખાનગી ચલો અને ફંક્શન્સ સામાન્ય રીતે જાહેર કરવામાં આવે છે.
- જાહેર પદ્ધતિઓ વ્યાખ્યાયિત કરવામાં આવે છે, અને તે ખાનગી સભ્યોને ઍક્સેસ કરી શકે છે.
- પરત કરેલ ઓબ્જેક્ટ સ્પષ્ટપણે જાહેર ઇન્ટરફેસને ખાનગી અમલીકરણો સાથે મેપ કરે છે.
ઉપયોગના કિસ્સાઓ: મોડ્યુલ્સના એન્કેપ્સ્યુલેશનને વધારવું, સ્વચ્છ અને કેન્દ્રિત જાહેર API પ્રદાન કરવું, અને મોડ્યુલના ઉપયોગને સરળ બનાવવો. લાઇબ્રેરી ડિઝાઇનમાં ઘણીવાર માત્ર જરૂરી કાર્યક્ષમતાઓ ખુલ્લી પાડવા માટે કાર્યરત છે.
૬. ડેકોરેટર પેટર્ન
ડેકોરેટર પેટર્ન એક ઓબ્જેક્ટમાં ગતિશીલ રીતે નવી જવાબદારીઓ ઉમેરે છે, તેની રચનામાં ફેરફાર કર્યા વિના. આ મૂળ ઓબ્જેક્ટને ડેકોરેટર ઓબ્જેક્ટમાં લપેટીને પ્રાપ્ત થાય છે. તે સબક્લાસિંગ માટે એક લવચીક વિકલ્પ પ્રદાન કરે છે, જે તમને રનટાઇમ પર કાર્યક્ષમતા વધારવાની મંજૂરી આપે છે.
// Component interface (base object)
class Pizza {
constructor() {
this.description = 'Plain Pizza';
}
getDescription() {
return this.description;
}
getCost() {
return 10;
}
}
// Decorator abstract class
class PizzaDecorator extends Pizza {
constructor(pizza) {
super();
this.pizza = pizza;
}
getDescription() {
return this.pizza.getDescription();
}
getCost() {
return this.pizza.getCost();
}
}
// Concrete Decorators
class CheeseDecorator extends PizzaDecorator {
constructor(pizza) {
super(pizza); this.description = 'Cheese Pizza';
}
getDescription() {
return `${this.pizza.getDescription()}, Cheese`;
}
getCost() {
return this.pizza.getCost() + 2;
}
}
class PepperoniDecorator extends PizzaDecorator {
constructor(pizza) {
super(pizza);
this.description = 'Pepperoni Pizza';
}
getDescription() {
return `${this.pizza.getDescription()}, Pepperoni`;
}
getCost() {
return this.pizza.getCost() + 3;
}
}
// Usage
let pizza = new Pizza();
pizza = new CheeseDecorator(pizza);
pizza = new PepperoniDecorator(pizza);
console.log(pizza.getDescription()); // Output: Plain Pizza, Cheese, Pepperoni
console.log(pizza.getCost()); // Output: 15
સમજૂતી:
- `Pizza` ક્લાસ મૂળભૂત ઓબ્જેક્ટ છે.
- `PizzaDecorator` એ અમૂર્ત ડેકોરેટર ક્લાસ છે. તે `Pizza` ક્લાસને વિસ્તારે છે અને તેમાં `pizza` ગુણધર્મ (લપેટેલો ઓબ્જેક્ટ) હોય છે.
- કોંક્રિટ ડેકોરેટર્સ (દા.ત., `CheeseDecorator`, `PepperoniDecorator`) `PizzaDecorator` ને વિસ્તારે છે અને ચોક્કસ કાર્યક્ષમતા ઉમેરે છે. તે પોતાની સુવિધાઓ ઉમેરવા માટે `getDescription()` અને `getCost()` પદ્ધતિઓને ઓવરરાઇડ કરે છે.
- ક્લાયંટ ગતિશીલ રીતે મૂળભૂત ઓબ્જેક્ટમાં તેની રચના બદલ્યા વિના ડેકોરેટર્સ ઉમેરી શકે છે.
ઉપયોગના કિસ્સાઓ: ગતિશીલ રીતે ઓબ્જેક્ટ્સમાં સુવિધાઓ ઉમેરવી, મૂળ ઓબ્જેક્ટના ક્લાસમાં ફેરફાર કર્યા વિના કાર્યક્ષમતા વધારવી, અને જટિલ ઓબ્જેક્ટ રૂપરેખાંકનોનું સંચાલન કરવું. UI સુધારણા માટે ઉપયોગી, હાલના ઓબ્જેક્ટ્સમાં તેમના મુખ્ય અમલીકરણમાં ફેરફાર કર્યા વિના વર્તણૂકો ઉમેરવી (દા.ત., લોગિંગ, સુરક્ષા તપાસ, અથવા પ્રદર્શન મોનિટરિંગ ઉમેરવું).
વિવિધ વાતાવરણમાં મોડ્યુલ્સનો અમલ
મોડ્યુલ સિસ્ટમની પસંદગી વિકાસ વાતાવરણ અને લક્ષ્ય પ્લેટફોર્મ પર આધાર રાખે છે. ચાલો જોઈએ કે વિવિધ પરિસ્થિતિઓમાં મોડ્યુલ્સનો અમલ કેવી રીતે કરવો.
૧. બ્રાઉઝર-આધારિત વિકાસ
બ્રાઉઝરમાં, તમે સામાન્ય રીતે ES Modules અથવા AMD નો ઉપયોગ કરો છો.
- ES Modules: આધુનિક બ્રાઉઝર્સ હવે ES Modules ને મૂળભૂત રીતે સપોર્ટ કરે છે. તમે તમારી જાવાસ્ક્રિપ્ટ ફાઇલોમાં `import` અને `export` સિન્ટેક્સનો ઉપયોગ કરી શકો છો, અને આ ફાઇલોને તમારા HTML માં `